"""
MCP组件基类和通用接口定义
"""

from abc import ABC, abstractmethod
from typing import Any, List, Optional

import mcp.types as types


class BaseMCPComponent(ABC):
    """MCP组件抽象基类"""
    
    def __init__(self, name: str):
        """初始化组件"""
        self._name = name
        self._tools_cache: Optional[List[types.Tool]] = None
        self.initialize()
        
    @property
    def name(self) -> str:
        """获取组件名称"""
        return self._name
    
    @abstractmethod
    def is_available(self) -> bool:
        """
        检查组件是否可用
        
        默认实现示例:
            return True  # 组件始终可用
            # 或
            return self._dependency_installed  # 根据依赖检查
        """
        pass
    
    def initialize(self) -> None:
        """
        初始化组件（子类可重写）
        
        默认实现示例:
            # 初始化连接池、线程池等资源
            self._executor = ProcessPoolExecutor(max_workers=4)
            # 或
            self._db_pool = create_connection_pool(...)
        
        注意:
            - 此方法在 __init__ 中自动调用
            - 如果不需要初始化，可以不重写
        """
        pass
    
    @abstractmethod
    def _get_tools_definition(self) -> List[types.Tool]:
        """
        获取工具定义（由子类实现）
        
        默认实现示例:
            return [
                types.Tool(
                    name="tool_name",
                    description="工具描述",
                    inputSchema={
                        "type": "object",
                        "properties": {
                            "param1": {"type": "string", "description": "参数1"},
                            "param2": {"type": "number", "description": "参数2"}
                        },
                        "required": ["param1"]
                    }
                ),
                # ... 更多工具
            ]
        """
        pass
    
    def get_tools(self) -> List[types.Tool]:
        """获取组件提供的MCP工具列表（带缓存）"""
        if self._tools_cache is None:
            self._tools_cache = self._get_tools_definition()
        return self._tools_cache
    
    @abstractmethod
    async def handle_tool_call(self, name: str, arguments: Any) -> List[types.TextContent]:
        """
        处理工具调用
        
        参数:
            name: 工具名称
            arguments: 工具参数（字典格式）
        
        返回:
            TextContent 列表，包含执行结果
        
        默认实现示例:
            if name == "tool_name":
                param1 = arguments.get("param1")
                param2 = arguments.get("param2", default_value)
                
                try:
                    # 执行工具逻辑
                    result = await self._execute_logic(param1, param2)
                    
                    # 返回成功结果
                    return [types.TextContent(
                        type="text",
                        text=f"✓ 执行成功\n\n结果: {result}"
                    )]
                except Exception as e:
                    # 返回错误信息
                    return [types.TextContent(
                        type="text",
                        text=f"✗ 执行失败\n\n错误: {str(e)}"
                    )]
            
            # 未知工具
            return [types.TextContent(
                type="text",
                text=f"未知工具: {name}"
            )]
        """
        pass
    
    def cleanup(self) -> None:
        """
        清理组件资源（子类可重写）
        
        默认实现示例:
            # 关闭线程池
            if self._executor:
                self._executor.shutdown(wait=True)
                self._executor = None
            
            # 关闭数据库连接
            if self._db_pool:
                self._db_pool.close()
                self._db_pool = None
        
        注意:
            - 此方法在上下文管理器退出时自动调用
            - 如果不需要清理，可以不重写
        """
        pass
    
    def __enter__(self):
        """上下文管理器入口"""
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """上下文管理器退出时清理资源"""
        self.cleanup()
    
    def __repr__(self) -> str:
        """组件字符串表示"""
        return f"<{self.__class__.__name__}(name='{self.name}')>"
